package com.google.srclib.data;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.google.srclib.dataset.StockRecordDataset;

/**
 * 
 * @author Yuyao Liang
 * 
 */
public class TADataset implements ITADataset {
	private int durationType = DurationType.DAYS;
	private List<LocalDate> dates = new ArrayList<LocalDate>();
	private List<String> TANames = new ArrayList<String>();
	private Map<String, List<Double>> dataPool = new HashMap<String, List<Double>>();

	public TADataset(int durationType) {
		super();
		this.durationType = durationType;
	}

	public TADataset(StockRecordDataset data, int durationType) {
		this(durationType);
		DateTimeFormatter fmt = DateTimeFormat.forPattern("MM/dd/yyyy");
		try {
			data.beforeFirst();
			while (data.next()) {
				double high = data.getDouble(StockRecordDataset.HIGH);
				double low = data.getDouble(StockRecordDataset.LOW);
				double open = data.getDouble(StockRecordDataset.OPEN);
				double close = data.getDouble(StockRecordDataset.CLOSE);
				double volumn = data.getDouble(StockRecordDataset.VOLUMN);
				double adjclose = data.getDouble(StockRecordDataset.ADJCLOSE);
				put(TAKeyName.High.getKey(), high);
				put(TAKeyName.Low.getKey(), low);
				put(TAKeyName.Open.getKey(), open);
				put(TAKeyName.Close.getKey(), close);
				put(TAKeyName.Volumn.getKey(), volumn);
				put(TAKeyName.AdjClose.getKey(), adjclose);
				put(fmt.parseLocalDate(data.getString(StockRecordDataset.DATE)));
			}
			data.beforeFirst();
		} catch (SQLException e) {

		}
	}

	public boolean isDaysType() {
		return durationType == DurationType.DAYS;
	}

	public boolean isWeeksType() {
		return durationType == DurationType.WEEKS;
	}

	public boolean isBiWeeksType() {
		return durationType == DurationType.BIWEEKS;
	}

	public boolean isMonthsType() {
		return durationType == DurationType.MONTHS;
	}

	public void put(LocalDate date) {
		dates.add(date);
	}

	public void put(String key, double value) {
		List<Double> list = dataPool.get(key);
		if (list == null) {
			list = new ArrayList<Double>();
			dataPool.put(key, list);
			TANames.add(key);
		}
		list.add(value);
	}

	public LocalDate[] getDates() {
		LocalDate[] result = new LocalDate[dates.size()];
		return dates.toArray(result);
	}

	@SuppressWarnings("deprecation")
	public Date[] getDateArray() {
		Date[] result = new Date[dates.size()];
		for (int i = 0; i < dates.size(); i++) {
			LocalDate ldate = dates.get(i);
			result[i] = new Date(ldate.getMonthOfYear() + "/"
					+ ldate.getDayOfMonth() + "/" + ldate.getYear());
		}
		return result;
	}

	public Double[] get(String key) {
		List<Double> list = dataPool.get(key);
		if (list == null) {
			return null;
		}
		Double[] result = new Double[list.size()];
		return list.toArray(result);
	}

	public double[] getArray(String key) {
		List<Double> list = dataPool.get(key);
		if (list == null) {
			return null;
		}
		double[] result = new double[list.size()];
		for (int i = 0; i < list.size(); i++) {
			result[i] = list.get(i);
		}
		return result;
	}

	public ITADataset cloneTo(ITADataset data) {
		for (LocalDate date : dates) {
			data.put(date);
		}

		Set<String> keys = dataPool.keySet();
		for (String name : keys) {
			List<Double> list = dataPool.get(name);
			for (Double value : list) {
				data.put(name, value);
			}
		}

		return data;
	}

}
